package pl.iachoo.ctl.tabory.dao.hibernate.services;

import java.io.Serializable;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Example;

public abstract class BaseDaoService<T extends Serializable> {

	private static final Logger log = Logger.getLogger(BaseDaoService.class);

	protected Session session = getSession();

	protected Session getSession() {
		try {
			SessionFactory sessionFactory = new Configuration().configure()
					.buildSessionFactory();
			Session openSession = sessionFactory.openSession();
			return openSession;
		} catch (Exception e) {
			log.error("Could not locate SessionFactory in JNDI", e);
			throw new IllegalStateException(
					"Could not locate SessionFactory in JNDI");
		}
	}

	protected void saveOrUpdate(T persistentInstance) {
		log.debug("Saving or updating instance: " + persistentInstance);
		try {
			session.beginTransaction();
			session.save(persistentInstance);
			session.getTransaction().commit();
		} catch (Exception e) {
			log.error("Save or update failed. ", e);
		}
	}

	protected void delete(T persistentInstance) {
		log.debug("Deleting persistentInstance: " + persistentInstance);
		try {
			session.beginTransaction();
			session.delete(persistentInstance);
			session.getTransaction().commit();
		} catch (Exception e) {
			log.error("Delete failed. ", e);
		}
	}

	@SuppressWarnings("unchecked")
	protected T load(Class<T> clazz, Serializable id) {
		log.debug("Loading persistentInstance");
		T load = null;
		try {
			session.beginTransaction();
			load = (T) session.load(clazz, id);
			session.getTransaction().commit();
		} catch (Exception e) {
			log.error("Load faild. ", e);
		}
		return load;
	}

	@SuppressWarnings("unchecked")
	protected List<T> loadList(Class<T> clazz, Object criterion) {
		List<T> result = null;
		try {
			session.beginTransaction();
			result = session.createCriteria(clazz)
					.add(Example.create(criterion)).list();
			session.getTransaction().commit();
		} catch (Exception e) {
			log.error("Load faild. ", e);
		}
		return result;

	}

}
